import LinkedList, { Node } from "./LinkedList";

export default class CircleList<T> extends LinkedList<T> {
  constructor() {
    super();
  }

  push(v: T) {
    const node = new Node(v);
    if (this.isEmpty()) {
      this._head = node;
    } else {
      const current = this.getNodeAt(this._size - 1)!;
      current.next = node;
    }
    node.next = this._head;
    this._size++;
  }

  insert(v: T, index: number): boolean {
    if (!this._isSafeIndex(index)) {
      return false;
    }

    const node = new Node(v);
    let current;
    if (index === 0) {
      if (this._head === null) {
        this._head = node;
        node.next = this._head;
      } else {
        node.next = this._head;
        this._head = node;
        current = this.getNodeAt(index - 1)!;
        current.next = this._head;
      }
    } else {
      const prev = this.getNodeAt(index - 1)!;
      const cur = prev?.next;
      prev.next = node;
      node.next = cur;
    }
    this._size++;
    return true;
  }

  removeAt(index: number): void {
    if (!this._isSafeIndex(index)) {
      return;
    }

    let current;
    if (index === 0) {
      if (this._size === 1) {
        this._head = null;
      } else {
        const tail = this.getNodeAt(this._size - 1)!;
        current = this._head;
        this._head = current?.next!;
        tail.next = this._head;
      }
    } else {
      const prev = this.getNodeAt(index - 1)!;
      current = prev?.next!;
      prev.next = current?.next;
    }
  }
}
